using System.Collections;
using System.Collections.Generic;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine.AddressableAssets;
using UnityEngine;
using System;
using System.Linq;
using Object = System.Object;
using UnityEngine.ResourceManagement.ResourceLocations;
public static class LoadSystem
{
    //也就是说游戏中的加载必须是有了直接用or 回调用, 不存在逻辑等加载这一说
    public static T LoadAsset<T>(string path) where T : UnityEngine.Object
    {
        if (SFrameworkGate.InEditor)
        {
#if DEBUG && UNITY_EDITOR
            return AssetDatabase.LoadAssetAtPath<T>(path);
#else
        
#endif
        }
        return default(T);
    }

    public static void LoadVAsset(VAsset asset)
    {
        int result = asset.assetType switch
        {
            0 => LoadVPrefab(asset),
            1 => LoadVAnimation(asset),
            2 => LoadVAudioClip(asset),
            _ => -1
        };
        table[asset.name] = asset;
    }
    private static int LoadVPrefab(VAsset asset)
    {

        if (SFrameworkGate.InEditor)
        {
            var p = asset as VPrefab;
            p.runtimePrefab = AssetDatabase.LoadAssetAtPath<GameObject>(asset.assetPath);
            return 1;
        }

        //异步不同委托的创建必然伴随大量action碎片垃圾
        Addressables.LoadAssetAsync<GameObject>(asset.assetPath).Completed += (e) =>
        {
            var p = asset as VPrefab;
            if (e.IsValid()) p.runtimePrefab = e.Result;
        };
        return 0; //这里的0实际上无意义, 只是为了匹配Swtich块的写法
    }
    private static int LoadVAnimation(VAsset asset)
    {
        if (SFrameworkGate.InEditor)
        {
            var p = asset as VAnimation;
            p.runtimeClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(asset.assetPath);
            return 1;
        }

        Addressables.LoadAssetAsync<AnimationClip>(asset.assetPath).Completed += (e) =>
        {
            var p = asset as VAnimation;
            if (e.IsValid()) p.runtimeClip = e.Result;
        };
        return 0;
    }
    private static int LoadVAudioClip(VAsset asset)
    {

        if (SFrameworkGate.InEditor)
        {
            var p = asset as VAudioClip;
            p.runtimeClip = AssetDatabase.LoadAssetAtPath<AudioClip>(asset.assetPath);
            return 1;
        }

        //异步不同委托的创建必然伴随大量action碎片垃圾
        Addressables.LoadAssetAsync<AudioClip>(asset.assetPath).Completed += (e) =>
        {
            var p = asset as VAudioClip;
            if (e.IsValid()) p.runtimeClip = e.Result;

        };
        return 0; //这里的0实际上无意义, 只是为了匹配Swtich块的写法
    }

    public static Dictionary<string, VAsset> table = new();
    /// <summary>
    /// 这里定义的资源是不需要被传入异步工作流的内存常驻资产
    /// </summary>
    public static void PreloadAssets()
    {
        VExcel_AssetLoadPath.Preload(LoadVAsset);
        VAnimationDefine.PreLoadAssets(LoadVAsset);
    }


    public static void UnloadAssets()
    {
        table?.Clear();
    }
    public static bool CheckAssetExist(string key)
    {
        foreach (var locator in Addressables.ResourceLocators)
        {
            if (locator.Locate(key, typeof(object), out IList<IResourceLocation> locations) && locations.Count > 0)
            {
                return true;
            }
        }
        return false;
    }

#if UNITY_EDITOR
    /// <summary>
    /// 从指定文件夹下的 FBX 文件中提取第一个 AnimationClip
    /// </summary>
    /// <param name="folderPath">例如："Animations/FBX"</param>
    /// <param name="fbxName">例如："Run.fbx"</param>
    /// <returns>提取到的第一个 AnimationClip，如果没有则返回 null</returns>
    public static AnimationClip LoadClipEditor(string folderPath, string fbxName)
    {
        // 拼接完整路径
        string fullAssetPath = Path.Combine("Assets", folderPath, fbxName).Replace("\\", "/");
        if (!(fullAssetPath.EndsWith(".fbx") || fullAssetPath.EndsWith(".FBX")))
        {
            fullAssetPath += ".fbx";
        }

        // 检查文件是否存在
        if (!File.Exists(fullAssetPath))
        {
            Debug.LogError($"找不到 FBX 文件: {fullAssetPath}");
            return null;
        }

        // 加载所有子资源
        Object[] assets = AssetDatabase.LoadAllAssetsAtPath(fullAssetPath);
        foreach (Object obj in assets)
        {
            if (obj is AnimationClip clip && !clip.name.Contains("__preview__"))
            {
                return clip;
            }
        }

        Debug.LogWarning($"FBX 文件中没有有效的 AnimationClip: {fbxName}");
        return null;
    }
    public static List<string> CollectName(string path)
    {
        List<string> files = new List<string>();

        string fullPath = Path.Combine(Application.dataPath, path);
        if (!Directory.Exists(fullPath))
        {
            Debug.LogWarning($"路径不存在: {fullPath}");
            return files;
        }

        string[] allFiles = Directory.GetFiles(fullPath, "*.*", SearchOption.AllDirectories);

        foreach (string file in allFiles)
        {
            if (file.EndsWith(".meta")) continue; // 忽略.meta文件

            // 转换为 Unity 的 Asset 路径
            string assetPath = file.Replace(Application.dataPath, "").Replace("\\", "/").Replace(path, "");

            files.Add(assetPath);
        }

        return files;
    }
#endif

    public static VAsset ToAsset(this string assetName)
    {
        return table[assetName];
    }

    public static GameObject ToPrefab(this string name) => (table[name] as VPrefab).runtimePrefab;
    public static AudioClip ToAudioClip(this string name) => (table[name] as VAudioClip).runtimeClip;

    public static AnimationClip ToAnimationClip(this string name) => (table[name] as VAnimation).runtimeClip;



}


//这种就要求资产在命名中就考虑到编程，从而使得资源id全局唯一
//这里简单的根据Demo写一个资产加载
public enum VAssetType
{
    Prefab = 0,
    AnimationClip = 1,
    AudioClip = 2,
    Effect = 3,

}

public class VAsset
{
    public string name;
    public string assetPath;
    public int assetType;
    public bool preload = true;
}

public class VPrefab : VAsset
{
    public GameObject runtimePrefab;
    public VPrefab()
    {
        assetType = 0;
    }
}
public class VAudioClip : VAsset
{
    public AudioClip runtimeClip;
    public VAudioClip()
    {
        assetType = 2;
    }
}

public class VAnimation : VAsset
{
    public string tags;
    public AnimationClip pre;
    public AnimationClip runtimeClip;
    public AnimationClip end;
    public VAnimation()
    {
        assetType = 1;
    }
    public bool hasPre => pre != null;
    public bool hasEnd => end != null;
    /// <summary>
    /// 提供一种索引遍历提取动画的方法
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public AnimationClip GetState(int index)
    {
        return index switch
        {
            0 => pre,
            1 => runtimeClip,
            2 => end,
            _ => null
        };
    }
    public override string ToString()
    {
        return name + ":" + tags;
    }
}

public class VAvatarMask : VAsset
{
    public AvatarMask runtimeMask;
    public VAvatarMaskID maskid;
}
